from kivy.logger import Logger
from nmj.sqlite.tables import Show
from nmjeditor.data_access.controller import CONFFILE, Controller
import ConfigParser
import logging
import mox
import os
import unittest


class Controller_TestCase(unittest.TestCase):
	def setUp(self):
		self.moxito = mox.Mox()

	def tearDown(self):
		self.moxito.UnsetStubs()
		self.moxito.VerifyAll()

	def _prepare_library(self, name):
		mock = self.moxito.CreateMockAnything(name)
		mock.base_directory = name
		return mock
	def _prepare_Controller(self,
			conffile_exists=True,
			has_media_section=True,
			has_libraries_key=True,
			libraries="'lib1','lib2'"):
		if not conffile_exists:
			has_media_section = has_libraries_key = False
		self.moxito.StubOutWithMock(os.path, "isfile")
		self.moxito.StubOutWithMock(os, "makedirs")
		self.mock_file_factory = self.moxito.CreateMockAnything()
		self.mock_nmj_factory = self.moxito.CreateMockAnything()
		self.mock_command_queue = self.moxito.CreateMockAnything()
		self.mock_drawer = self.moxito.CreateMockAnything()
		self.mock_message = self.moxito.CreateMockAnything()
		mock_file = self.moxito.CreateMockAnything()
		self.mock_config_factory = self.moxito.CreateMockAnything()
		mock_config = self.moxito.CreateMockAnything()
		os.path.isfile(CONFFILE).AndReturn(conffile_exists)
		if not conffile_exists:
			os.makedirs(os.path.dirname(CONFFILE))
			self.mock_file_factory(CONFFILE, "w+").AndReturn(mock_file)
			mock_file.close()
		self.mock_config_factory().AndReturn(mock_config)
		self.mock_nmj_factory().AndReturn(self.mock_nmj_factory)
		mock_config.read(CONFFILE)
		if not has_media_section:
			mock_config.get("media", "libraries").AndRaise(ConfigParser.NoSectionError("media"))
			self.mock_nmj_factory.libraries = []
		elif not has_libraries_key:
			mock_config.get("media", "libraries").AndRaise(ConfigParser.NoOptionError("media", "libraries"))
			self.mock_nmj_factory.libraries = []
		else:
			self.mock_nmj_factory.libraries = [self._prepare_library(lib) for lib in eval(libraries)]
			mock_config.get("media", "libraries").AndReturn(libraries)
			for lib in eval(libraries):
				self.mock_nmj_factory.add_library(lib)
		mocks = [
			self.mock_file_factory,
			self.mock_nmj_factory,
			mock_file,
			self.mock_config_factory,
			mock_config,
			os.path.isfile
		]
		if not conffile_exists:
			mocks.append(os.makedirs)
		mox.Replay(*mocks)
		controller = Controller(
			command_queue = self.mock_command_queue,
			drawer=self.mock_drawer,
			file_factory=self.mock_file_factory,
			config_factory=self.mock_config_factory,
			nmj_factory=self.mock_nmj_factory,
			message_factory = self.mock_message,
		)
		controller.thread_started()
		mox.Reset(*mocks)
		return controller


	def test_creation_01(self):
		"Controller: Create Controller, without config"
		controller = self._prepare_Controller(has_libraries_key=False)
		self.failIf(controller.get_libraries())

	def test_creation_02(self):
		"Controller: Create Controller, without library configuration"
		controller = self._prepare_Controller(conffile_exists=False)
		self.failIf(controller.get_libraries())

	def test_creation_03(self):
		"Controller: Create Controller, with library configuration"
		controller = self._prepare_Controller()
		self.failUnless(controller.get_libraries())

	def _prepare_notify(self, method, *args, **kwargs):
		self.mock_message(method, *args, **kwargs).AndReturn(self.mock_message)
		self.mock_command_queue.put(self.mock_message)
		self.mock_drawer.ask_update()

	def test_get_shows_01(self):
		"Retreive Shows for libraries, nominal case"
		shows = []
		for rank in range(2):
			mock = self.moxito.CreateMockAnything()
			mock.detail_poster = "poster%d" % rank
			mock.wallpaper = "wallpaper%d" % rank
			shows.append(mock)
		controller = self._prepare_Controller(libraries="'lib',")
		self.mock_nmj_factory.get_all(Show).AndReturn(shows)
		self._prepare_notify("on_show_max", 2)
		for show in shows:
			self._prepare_notify("on_show", show)
		self.moxito.ReplayAll()
		controller.get_shows()

	def test_get_synopsis_01(self):
		"Retreive Synopsis for libraries, show instance given"
		synopsis = "Descritption of the show"
		show = "show"
		controller = self._prepare_Controller()
		self.mock_nmj_factory.get_synopsis(show=show, title=None).AndReturn(synopsis)
		self._prepare_notify("on_synopsis", synopsis)
		self.moxito.ReplayAll()
		controller.get_synopsis(show=show)

	def test_get_synopsis_02(self):
		"Retreive Synopsis for libraries, show title given"
		synopsis = "Descritption of the show"
		title = "show title"
		controller = self._prepare_Controller()
		self.mock_nmj_factory.get_synopsis(show=None, title=title).AndReturn(synopsis)
		self._prepare_notify("on_synopsis", synopsis)
		self.moxito.ReplayAll()
		controller.get_synopsis(title=title)

if __name__ == "__main__":
	Logger.setLevel(logging.CRITICAL)
	unittest.main()

